//统一单例的状态管理
import Singleton from '../Base/Singleton'

// 给监听事件定义接口类型加入上下文对象
interface Item {
  func: Function
  ctx: unknown
}

//泛型单例模式，单例模式一个类只有一个实例并提供全局访问点
export default class EventManager extends Singleton {
  static get Instance() {
    return super.GetInstance<EventManager>()
  }
  // 实现一个事件中心维护一个map,key是事件类型value是方法
  private eventDic: Map<string, Array<Item>> = new Map()

  on(eventName: string, func: Function, ctx?: unknown) {
    if (this.eventDic.has(eventName)) {
      this.eventDic.get(eventName).push({ func, ctx })
    } else {
      this.eventDic.set(eventName, [{ func, ctx }])
    }
  }

  off(eventName: string, func: Function) {
    if (this.eventDic.has(eventName)) {
      const index = this.eventDic.get(eventName).findIndex(i => i.func === func)
      index > -1 && this.eventDic.get(eventName).splice(index, 1)
    }
  }

  emit(eventName: string, ...params: unknown[]) {
    if (this.eventDic.has(eventName)) {
      this.eventDic.get(eventName).forEach(({ func, ctx }) => {
        ctx ? func.apply(ctx, params) : func(...params)
      })
    }
  }
  clear() {
    this.eventDic.clear()
  }
}
